#ifndef REMOTE_SERVER_CONTROL_CONTROL_SESSION_H_
#define REMOTE_SERVER_CONTROL_CONTROL_SESSION_H_

#include "vzconn/conn/tcpconnect.h"
#include "remote/stanza/querystanza.h"
#include <set>

namespace remote {

class ControlSession : public boost::noncopyable,
  public boost::enable_shared_from_this < ControlSession > {
 public:
  typedef boost::shared_ptr<ControlSession> Ptr;

  ControlSession(boost::asio::io_service &io_service,
                 vzconn::VzConnect::Ptr tcp_connect);
  virtual ~ControlSession();

  boost::signals2::signal<void(
    ControlSession::Ptr control_session,
    bool *res)> SignalRegisterEvent;
  boost::signals2::signal<void(
    ControlSession::Ptr control_session)> SignalCloseEvent;
  boost::signals2::signal<void(
    ControlSession::Ptr control_session,
    QueryStanza::Ptr stanza)> SignalSessionEvent;

  bool StartSession();
  void StopSession();

  const std::string session_name() {
    return session_name_;
  }
  bool AsyncWrite(QueryStanza::Ptr stanza);
 private:
  // With VzConnect callback function
  void OnConnectError(vzconn::VzConnect::Ptr connect,
                      const boost::system::error_code& err);
  void OnConnectWrite(vzconn::VzConnect::Ptr connect);
  void OnConnectRead(vzconn::VzConnect::Ptr connect,
                     const char* buffer, int size, int flag);
  void ProcessRegister(vzconn::VzConnect::Ptr connect,
                       QueryStanza::Ptr stanza);
 private:
  boost::asio::io_service &io_service_;
  vzconn::VzConnect::Ptr tcp_connect_;
  std::string session_name_;
  std::string remote_addr_;
};

}

#endif  // REMOTE_SERVER_CONTROL_CONTROL_SESSION_H_
